<?php
class Entry_Manager extends Model {
	
	private $_current_blogger_id;
	
	function Entry_Manager() {
		parent::Model();
		$this->_current_blogger_id = 0;
		// my custom lib.
		$this->load->library('common');
	}
	
	function SetCurrentBloggerID($current_blogger_id) {
		$this->_current_blogger_id = $current_blogger_id;
	}
	
	function _check_blogger_id() {
		if($this->_current_blogger_id == 0) {
			throw new Exception('ERROR: Invalid Blogger-ID!');
		}
	}
	
	function GetCategoryTitleByID($cate_id) {
		if($cate_id == 1) {
			return '未分类'; // languages?! TODO
		} else {
			$qry = $this->db->query('SELECT `title` FROM `nt_categories` WHERE `id` = ?', array($cate_id));
			if($qry->num_rows() < 1) {
				throw new Exception('No such Category!');
			} else {
				return $qry->row()->title;
			}
		}
	}
	
	// here $entry should be an array?
	function AddEntry($entry) {
		$this->_check_blogger_id();
		
		if($this->_current_blogger_id != $entry['blogger_id']) {
			throw new Exception('ERROR: Wrong Blogger-ID!');
		}
		
		$category_title = $this->GetCategoryTitleByID($entry['category_id']);
		$parms = array(
			'blogger_id' => $entry['blogger_id'],
			'post_time' => $entry['post_time'],
			'title' => $entry['title'],
			'author_name' => $entry['author_name'],
			'expression' => $entry['expression'],
			'ip' => $entry['ip'],
			'category_id' => $entry['category_id'],
			'category_title' => $category_title,
			'allow_comment' => $entry['allow_comment'],
			'state' => $entry['state'],
			'tags' => $entry['tags'],
			'entry_url' => $entry['entry_url']
		);
		$this->db->insert('nt_entries', $parms);
		$new_entry_id = $this->db->insert_id();
		
		$parms1 = array(
			'entry_id' => $new_entry_id,
			'content' => $entry['content']
		);
		$this->db->insert('nt_entry_data', $parms1);
		// if not draft, then update entry_num
		if($entry['state'] < 99) {
			$this->db->query('UPDATE `nt_blogger_info` SET `entry_num` = `entry_num` + 1, `last_update_time` = ? WHERE `blogger_id` = ?', array($entry['post_time'], $entry['blogger_id']));
		}
		// at caller side, must process Tags
		return $new_entry_id;
	}
	
	function SetBloggerLastUpdateTime() {
		$this->_check_blogger_id();
		
		$qry = $this->db->query('SELECT `post_time` FROM `nt_entries` WHERE `blogger_id` = ? AND `state` < 99 ORDER BY `post_time` DESC, `id` DESC LIMIT 1', array($this->_current_blogger_id));
		if($qry->num_rows() > 0) {
			$lut = $qry->row()->post_time;
		} else {
			$lut = NULL;
		}
		$this->db->query('UPDATE `nt_blogger_info` SET `last_update_time` = ? WHERE `blogger_id` = ?', array($lut, $this->_current_blogger_id));
	}
	
	// re-count non-draft entries, to update entry_num field. (in favor of state -> 99)
	function RefreshEntryNum() {
		$qry = $this->db->query('SELECT COUNT(*) AS entry_num FROM `nt_entries` WHERE `blogger_id` = ? AND `state` < 99', array($this->_current_blogger_id));
		$this->db->query('UPDATE `nt_blogger_info` SET `entry_num` = ? WHERE `blogger_id` = ?', array($qry->row()->entry_num, $this->_current_blogger_id));
	}
	
	function UpdateEntry($entry) {
		$this->_check_blogger_id();
		
		if($this->_current_blogger_id != $entry['blogger_id']) {
			throw new Exception('ERROR: Wrong Blogger-ID!');
		}
		
		$category_title = $this->GetCategoryTitleByID($entry['category_id']);
		$parms = array(
			'blogger_id' => $entry['blogger_id'],
			'post_time' => $entry['post_time'],
			'title' => $entry['title'],
			'author_name' => $entry['author_name'],
			'expression' => $entry['expression'],
			'ip' => $entry['ip'],
			'category_id' => $entry['category_id'],
			'category_title' => $category_title,
			'allow_comment' => $entry['allow_comment'],
			'state' => $entry['state'],
			'tags' => $entry['tags'],
			'entry_url' => $entry['entry_url']
		);
		$this->db->where('id', $entry['id']);
		$this->db->update('nt_entries', $parms);
		
		$parms1 = array(
			'content' => $entry['content']
		);
		$this->db->where('entry_id', $entry['id']);
		$this->db->update('nt_entry_data', $parms1);
		
		$this->RefreshEntryNum();
		$this->SetBloggerLastUpdateTime();
		// at caller side, must process Tags
	}
	
	function DeleteEntry($entry_id) {
		$this->_check_blogger_id();
		
/*		$qry = $this->db->query('SELECT `blogger_id` FROM `nt_entries` WHERE `id` = ?', array($entry_id));
		if($qry->row()->blogger_id != $this->_current_blogger_id) {
			throw new Exception('The to be deleted Entry does not belong to the provided Blogger!');
		}*/
		
		$this->db->query('DELETE FROM `nt_entry_data` WHERE `entry_id` = ?', array($entry_id));
		$this->db->query('DELETE FROM `nt_entries` WHERE `id` = ? AND `blogger_id` = ?', array($entry_id, $this->_current_blogger_id));
		$this->RefreshEntryNum();
		// delete tags
		$this->db->query('DELETE FROM `nt_tags` WHERE `entry_id` = ? AND `blogger_id` = ?', array($entry_id, $this->_current_blogger_id));
		// delete comments
		$qry = $this->db->query('SELECT `id` FROM `nt_comments` WHERE `entry_id` = ?', array($entry_id));
		if($qry->num_rows() > 0) {
			$cids = array();
			foreach($qry->result() as $r) {
				array_push($cids, $r->id);
			}
			$cids1 = implode(', ', $cids);
			$this->db->query('DELETE FROM `nt_comment_data` WHERE `comment_id` IN (' . $cids1 . ')');
			$this->db->query('DELETE FROM `nt_comments` WHERE `entry_id` = ?', array($entry_id));
		}
		// update order :)
		$this->SetBloggerLastUpdateTime();
	}
	
	function BatchDeleteEntries($arr_entry_ids) {
		$this->_check_blogger_id();
		
		$str_entry_ids = implode(', ', $arr_entry_ids);
		
/*		$qry = $this->db->query('SELECT `blogger_id` FROM `nt_entries` WHERE `id` IN (?)', array($str_entry_ids));
		if($qry->num_rows() != 1) {
			throw new Exception('ERROR: Not all entries belong to the provided Blogger!');
		} else {
			if($qry->row()->blogger_id != $this->_current_blogger_id) {
				throw new Exception('ERROR: Entries do not belong to the provided Blogger!');
			}
		}*/
		
		$this->db->query('DELETE FROM `nt_entry_data` WHERE `entry_id` IN (' . $str_entry_ids . ')');
		$this->db->query('DELETE FROM `nt_entries` WHERE `id` IN (' . $str_entry_ids . ') AND `blogger_id` = ?', array($this->_current_blogger_id));
		$this->RefreshEntryNum();
		// delete tags
		$this->db->query('DELETE FROM `nt_tags` WHERE `entry_id` IN (' . $str_entry_ids . ') AND `blogger_id` = ?', array($this->_current_blogger_id));
		// delete comments
		$qry = $this->db->query('SELECT `id` FROM `nt_comments` WHERE `entry_id` IN (' . $str_entry_ids . ')');
		if($qry->num_rows() > 0) {
			$cids = array();
			foreach($qry->result() as $r) {
				array_push($cids, $r->id);
			}
			$cids1 = implode(', ', $cids);
			$this->db->query('DELETE FROM `nt_comment_data` WHERE `comment_id` IN (' . $cids1 . ')');
			$this->db->query('DELETE FROM `nt_comments` WHERE `entry_id` IN (' . $str_entry_ids . ')');
		}
		$this->SetBloggerLastUpdateTime();
	}
	
	function RetrieveEntry($entry_id) {
		$qry = $this->db->query('SELECT e.`id`, e.`blogger_id`, e.`post_time`, e.`title`, e.`author_name`, e.`expression`, ed.`content`, e.`comment_num`, e.`ip`, e.`category_id`, e.`category_title`, e.`allow_comment`, e.`state`, e.`tags`, e.`entry_url` FROM `nt_entry_data` ed JOIN `nt_entries` e ON ed.`entry_id` = e.`id` WHERE e.`id` = ? AND e.blogger_id = ?', array($entry_id, $this->_current_blogger_id));
		if($qry->num_rows() < 1) {
			throw new Exception('ERROR: Specified Entry does not exist! / not belongs to this Blogger!');
		} else {
			return $qry->row();
		}
	}
	
	// Get comments (authed) of one entry
	function GetEntryCommentList($entry_id) {
		$qry = $this->db->query('SELECT c.`id`, c.`author_name`, c.`email`, c.`post_time`, cd.`content`, c.`ip`, c.`url`, c.`by_blogger_id` FROM `nt_comment_data` cd JOIN `nt_comments` c ON cd.`comment_id` = c.`id` WHERE c.`entry_id` = ? AND c.`state` = 1 ORDER BY c.`id`', array($entry_id));
		return $qry->result();
	}
	
	function CategorizeEntries($arr_entry_ids, $cate_id) {
		$str_entry_ids = implode(', ', $arr_entry_ids);
		$cate_title = $this->GetCategoryTitleByID($cate_id);
		$this->db->query('UPDATE `nt_entries` SET `category_id` = ?, `category_title` = ? WHERE `blogger_id` = ? AND `id` IN (' . $str_entry_ids . ')', array($cate_id, $cate_title, $this->_current_blogger_id));
	}
	
	function BatchSetEntryState($arr_entry_ids, $new_state) {
		$str_entry_ids = implode(', ', $arr_entry_ids);
		if($new_state < 99) {
			// for drafts, change their post_time to Now()
			$this->db->query('UPDATE `nt_entries` SET `post_time` = ? WHERE `blogger_id` = ? AND `state` = 99 AND `id` IN (' . $str_entry_ids . ')', array($this->common->Now(), $this->_current_blogger_id));
		}
		$this->db->query('UPDATE `nt_entries` SET `state` = ? WHERE `blogger_id` = ? AND `id` IN (' . $str_entry_ids . ')', array($new_state, $this->_current_blogger_id));
		$this->RefreshEntryNum();
		$this->SetBloggerLastUpdateTime();
	}
	
	function BatchSetEntryTagInfo($arr_entry_ids, $tag_text) {
		$str_entry_ids = implode(', ', $arr_entry_ids);
		$this->db->query('UPDATE `nt_entries` SET `tags` = ? WHERE `id` IN (' . $str_entry_ids . ') AND `blogger_id` = ?', array($tag_text, $this->_current_blogger_id));
		// TODO (from caller side?) Tag_Manager->UpdateTags
	}
	
	// Get one newer entry - nirvana 0.6 has a typo here? ;p
	function GetNextEntryInfo($entry_id) {
		$qry = $this->db->query('SELECT `id`, `title` FROM `nt_entries` WHERE `post_time` > (SELECT `post_time` FROM `nt_entries` WHERE `id` = ?) AND `blogger_id` = ? AND `state` = 1 ORDER BY `post_time` LIMIT 1', array($entry_id, $this->_current_blogger_id));
		if($qry->num_rows() < 1) {
			return NULL; // no newer
		} else {
			return $qry->row();
		}
	}
	
	// Get one older entry
	function GetPrevEntryInfo($entry_id) {
		$qry = $this->db->query('SELECT `id`, `title` FROM `nt_entries` WHERE `post_time` < (SELECT `post_time` FROM `nt_entries` WHERE `id` = ?) AND `blogger_id` = ? AND `state` = 1 ORDER BY `post_time` DESC LIMIT 1', array($entry_id, $this->_current_blogger_id));
		if($qry->num_rows() < 1) {
			return NULL;
		} else {
			return $qry->row();
		}
	}
}
?>